package com.cgah

import grails.plugins.springsecurity.SpringSecurityService
import javax.servlet.http.HttpServletResponse
import grails.plugin.mail.MailService

/**
 * 1.  yeah i extended it and threw in some BASIC NECESSARY SETUPS!
 */
class BidControllerTests extends AbstractUnitTest {
    Customer mockCustomerSeller;
    Listing mockListing;

    void setUp() {
        super.setUp()

        // 2.  Since you cannot override the behavior of <Domain>.save or <Domain>.validate
        // for your mocks, you have to mock the rest of the dependencies, soOO much fail
        mockDomain(Customer)
        mockDomain(Listing)
        mockDomain(Bid)

        // 3.  I cannot believe this template crap isn't done in the grails test classes
        setupForClass(BidController.newInstance());

        // 4.  this is SOOOOOO unnecessary.  creating 'REAL' dependencies is so fail
        // what a fail test framework.  what kind of freaking frail fail test framework is this?
        mockCustomerSeller = new Customer(username: "blabababa",
                emailAddress: "asdf@asdf.com",
                createdDate: new Date(),
                password: "12312312",
                enabled: true);
        mockListing = new Listing(createdDateTime:new Date(),
                description: "asdf",
                seller:mockCustomerSeller,
                startingBidPrice: 11.0f,
                name: "test",
                endDateTime: (new Date())+1);

        mockCustomerSeller.save(flush:true);
        mockListing.save(flush:true);

        assertTrue(Listing.list().size() >= 1);
        assertTrue(Customer.list().size() >= 1);

        // 5.  this is also so fail, because save will silently FAIL, and you can't tell
        // it to just say "yes, i worked!", nope you can't w/o overriding it
        // so we HAVE TO PUT VALID VALUES HERE!
        params.put('listing.id', mockListing.id);
        params.put('amount', mockListing.startingBidPrice + 1.0f)
    }

    protected void tearDown() {
/*      // looks like the framework actually does something useful
        Customer.list()*.delete();
        Bid.list()*.delete();
        Listing.list()*.delete();
*/
        super.tearDown()
    }


    // UI-4: The action of placing a new bid will display a message to the user indicating that the bid was successful
    // (Controller Unit Test)
    void testAsyncAddBidDisplaySuccessMessage() {
        def springSecurityService = mockFor(SpringSecurityService, false);
        def mailService = mockFor(MailService, false);
        def bidService = mockFor(BidService, false);

        springSecurityService.demand.getCurrentUser(1..1) {-> return mockCustomerSeller }
        mailService.demand.sendMail(1..1){-> return true }
        bidService.demand.save() {def a, def b -> return new Bid()}

        controller.springSecurityService = springSecurityService.createMock();
        controller.mailService = mailService.createMock();
        controller.bidService = bidService.createMock();


        def result = controller.asyncAddBid();
        // BTW  util.converters.JSON - WORK AROUND FOR 'self claimed MINOR' BUG.  MAJOR BUG IMO
        // see bug http://jira.grails.org/browse/GRAILS-6222
        def jsonObj = util.converters.JSON.parse(controller.response.contentAsString);
        assertTrue(jsonObj.message.toLowerCase().contains("successfull"));
        assertEquals(HttpServletResponse.SC_OK, controller.response.status);
    }


    // UI-5: An error message will be displayed if placing a new bid is unsuccessful
    // (for instance if the new bid amount does not pass validation requirements) (Controller Unit Test)

    void testAsyncAddBidDisplayErrorMessage() {
        def springSecurityService = mockFor(SpringSecurityService);
        def bidServiceMock = mockFor(BidService, false);

        params.put('amount', mockListing.startingBidPrice - 1.0f) // less money = fail

        springSecurityService.demand.getCurrentUser() {-> return mockCustomerSeller }
        bidServiceMock.demand.save(1..1) {def b, def a ->  return false }

        controller.springSecurityService = springSecurityService.createMock();
        controller.bidService = bidServiceMock.createMock();

        def result = controller.asyncAddBid();
        assertTrue(controller.response.contentAsString.toString().toLowerCase().contains("failed"));
        assertEquals(HttpServletResponse.SC_BAD_REQUEST, controller.response.status);

    }


}




